package com.jnc.pay.core.vertx.processor;

import com.jnc.pay.core.vertx.verticle.MultiThreadedWorkerVerticle;
import com.jnc.pay.core.vertx.verticle.StandardVerticle;
import com.jnc.pay.core.vertx.verticle.WorkerVerticle;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @Author: jjn
 * @Date: 2019/2/1 18:04
 * @Desc: 注册verticle
 * 1、BeanPostProcessor接口作用是：如果我们需要在Spring容器完成Bean的实例化、
 *   配置和其他的初始化前后添加一些自己的逻辑处理，
 *   我们就可以定义一个或者多个BeanPostProcessor接口的实现，然后注册到容器中。
 */
@Slf4j
@Component
public class SpringVertxProcessor implements BeanPostProcessor {

    @Autowired
    private Vertx vertx;

    /**
     * BeanPostProcessor前置处理
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        return o;
    }

    /**
     * BeanPostProcessor后置处理
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        //当对象是AbstractVerticle的子类时
        if(o instanceof AbstractVerticle){
            log.debug("vertx deploy verticle:{}", o);

            if(o instanceof StandardVerticle){
                StandardVerticle verticle = (StandardVerticle) o;
                vertx.deployVerticle(verticle);
            }else if(o instanceof WorkerVerticle){
                WorkerVerticle verticle = (WorkerVerticle) o;
                vertx.deployVerticle(verticle, getWorkOptions());
            }else if(o instanceof MultiThreadedWorkerVerticle){
                MultiThreadedWorkerVerticle verticle = (MultiThreadedWorkerVerticle) o;
                vertx.deployVerticle(verticle, getMultiThreadWorkOptions());
            }else{
                AbstractVerticle verticle = (AbstractVerticle) o;
                vertx.deployVerticle(verticle);
            }
        }
        return o;
    }

    /**
     * 获取WorkerVerticle参数配置
     * @return
     */
    @Bean
    public DeploymentOptions getWorkOptions(){
        DeploymentOptions options = new DeploymentOptions();
        //将某个verticle作为worker verticle部署
        options.setWorker(true);
        return options;
    }

    /**
     * 获取多线程版WorkerVerticle参数配置
     * @return
     */
    @Bean
    public DeploymentOptions getMultiThreadWorkOptions(){
        DeploymentOptions options = new DeploymentOptions();
        //将某个verticle作为worker verticle部署
        options.setWorker(true);
        //将verticle标注为多线程版
        //options.setMultiThreaded(true);
        return options;
    }

}
